package com.xiaobias.distributed.pan.seurity.service;

import cn.hutool.json.JSONUtil;
import com.xiaobias.distributed.pan.seurity.entity.BaiduAccessTokenBean;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


@Service
public class BaiduOAuth2AccessTokenResponseClient implements OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> {
    private RestTemplate restTemplate;

    private RestTemplate getRestTemplate() {
        if (this.restTemplate == null) {
            this.restTemplate = new RestTemplate();
        }
        return this.restTemplate;
    }

    public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationGrantRequest) {
        ClientRegistration clientRegistration = authorizationGrantRequest.getClientRegistration();
        OAuth2AuthorizationExchange oAuth2AuthorizationExchange = authorizationGrantRequest.getAuthorizationExchange();

        String tokenUrl = String.format("%s?grant_type=authorization_code&code=%s&client_id=%s&client_secret=%s&redirect_uri=%s",
                clientRegistration.getProviderDetails().getTokenUri(),
                oAuth2AuthorizationExchange.getAuthorizationResponse().getCode(),
                clientRegistration.getClientId(),
                clientRegistration.getClientSecret(),
                oAuth2AuthorizationExchange.getAuthorizationResponse().getRedirectUri());

        String tmpTokenResponse = getRestTemplate().getForObject(tokenUrl, String.class, new Object[0]);
        BaiduAccessTokenBean bean = JSONUtil.toBean(tmpTokenResponse, BaiduAccessTokenBean.class);

        OAuth2AccessToken.TokenType accessTokenType = OAuth2AccessToken.TokenType.BEARER;
        Map<String, Object> additionalParameters = new LinkedHashMap<>();
        HashSet<String> scopes = new HashSet<>(Arrays.asList(bean.getScope().split(" ")));

        return OAuth2AccessTokenResponse.withToken(bean.getAccess_token()).tokenType(accessTokenType).expiresIn(bean.getExpires_in().intValue()).scopes(scopes).additionalParameters(additionalParameters).build();
    }
}